#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <pthread.h>

#define SERVER_PORT 5432
#define MAX_LINE 256

void *receive_thread(void *arg) {
    int sock = *((int *)arg);
    char buf[MAX_LINE];
    int len;

    while ((len = recv(sock, buf, sizeof(buf), 0)) > 0) {
        buf[len] = '\0';
        printf("Server: %s\n", buf);
    }

    return NULL;
}

void *send_thread(void *arg) {
    int sock = *((int *)arg);
    char buf[MAX_LINE];

    while (fgets(buf, sizeof(buf), stdin) != NULL) {
        buf[strcspn(buf, "\n")] = 0; // Remove newline character
        send(sock, buf, strlen(buf), 0);
    }

    return NULL;
}

int main(int argc, char *argv[]) {
    struct sockaddr_in sin;
    struct hostent *hp;
    int s;
    pthread_t receive_tid, send_tid;
    int *sock = malloc(sizeof(int));

    if (argc != 2) {
        fprintf(stderr, "Usage: %s <Server IP>\n", argv[0]);
        exit(1);
    }

    hp = gethostbyname(argv[1]);
    if (hp == NULL) {
        fprintf(stderr, "Error: gethostbyname\n");
        exit(1);
    }

    bzero((char *)&sin, sizeof(sin));
    sin.sin_family = AF_INET;
    bcopy((char *)hp->h_addr, (char *)&sin.sin_addr.s_addr, hp->h_length);
    sin.sin_port = htons(SERVER_PORT);

    s = socket(PF_INET, SOCK_STREAM, 0);
    if (s < 0) {
        perror("Error: socket");
        exit(1);
    }

    if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
        perror("Error: connect");
        exit(1);
    }

    *sock = s;

    pthread_create(&receive_tid, NULL, receive_thread, (void *)sock);
    pthread_create(&send_tid, NULL, send_thread, (void *)sock);

    pthread_join(receive_tid, NULL);
    pthread_join(send_tid, NULL);

    close(s);
    free(sock);
    return 0;
}
